package com.google.code.mochaccino.framework.junit;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Simple Assertion Method that are easier/more pleasant to use than JUnit methods. Less verbose. */
public final class Validation {

	public static <T> boolean contains( Collection<T> array, T value ) {
		if ( !isNotNull( array ) ) {
			return false;
		}
		if ( !isNotNull( value ) ) {
			return false;
		}
		for ( T v : array ) {
			if ( Validation.eq( v, value ) ) {
				return true;
			}
		}
		return fail( "Expected collection to contain %s", value );
	}

	public static <T> boolean contains( T[] array, T value ) {
		if ( !isNotNull( array ) ) {
			return false;
		}
		if ( !isNotNull( value ) ) {
			return false;
		}
		for ( T v : array ) {
			if ( Validation.eq( v, value ) ) {
				return true;
			}
		}
		return fail( "Expected array to contain %s", value );
	}

	public static <T> boolean containsAll( T[] expected, T[] actual ) {
		if ( isNull( expected ) ) {
			return false;
		}
		if ( isNull( actual ) ) {
			return false;
		}
		return containsAll( Arrays.asList( expected ), Arrays.asList( actual ) );
	}

	public static <T> boolean containsAll( Collection<T> expected, Collection<T> actual ) {
		if ( isNull( expected ) ) {
			return false;
		}
		if ( isNull( actual ) ) {
			return false;
		}
		if ( expected.containsAll( actual ) ) {
			return true;
		}
		return fail( "Expected collection does not contain all values from specified collection." );
	}

	public static <K,V> boolean containsEntry( Map<K,V> map, K key, V value ) {
		if ( !isNotNull( map ) ) {
			return false;
		}

		if ( !isNotNull( key ) ) {
			return false;
		}

		if ( !map.containsKey( key ) ) {
			return fail( "Map does not contain key %s", key );
		}

		if ( Validation.eq( map.get( key ), value ) ) {
			return fail( "Map does not conain key %s value %s pair", key, value );
		}
		return true;
	}

	public static <K,V> boolean containsKey( Map<K,V> map, K key ) {
		if ( !isNotNull( map ) ) {
			return false;
		}

		if ( !isNotNull( key ) ) {
			return false;
		}

		if ( !map.containsKey( key ) ) {
			return fail( "Map does not contain key %s", key );
		}

		return true;
	}

	public static <K,V> boolean containsValue( Map<K,V> map, V value ) {
		if ( !isNotNull( map ) ) {
			return false;
		}

		if ( !isNotNull( value ) ) {
			return false;
		}

		if ( !map.containsValue( value ) ) {
			return fail( "Map does not contain value %s", value );
		}
		return true;
	}

	public static <T> boolean different( T expected, T actual ) {
		if ( expected == actual ) {
			return fail( "Object %s same to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean empty( Collection<T> value ) {
		return sizeEq( value, 0 );
	}

	public static <T> boolean sizeEq( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}

		if ( array.size() != expectedSize ) {
			return fail( "Collection length %s is not equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T,V> boolean empty( Map<T,V> value ) {
		return sizeEq( value, 0 );
	}

	public static <K,V> boolean sizeEq( Map<K,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}

		if ( array.size() != expectedSize ) {
			return fail( "Map length %s is not equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean empty( T[] value ) {
		return sizeEq( value, 0 );
	}

	public static <T> boolean sizeEq( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length != expectedSize ) {
			return fail( "Array length %s is not equal to expected value %s", array.length, expectedSize );
		}
		return true;
	}

	public static <T> boolean eq( boolean[] expected, boolean[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( byte[] expected, byte[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( char[] expected, char[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( double[] expected, double[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( float[] expected, float[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( int[] expected, int[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( long[] expected, long[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <K,V> boolean eq( Map<K,V> expected, Map<K,V> actual ) {
		if ( expected == null && actual == null ) {
			return true;
		}
		if ( expected != null && actual == null ) {
			return fail( "Expected %s not equals to %s", expected, "null" );
		}
		if ( expected == null && actual != null ) {
			return fail( "Expected %s not equals to %s", "null", actual );
		}
		if ( expected != null && actual != null ) {
			if ( !eq( expected.keySet(), actual.keySet() ) ) {
				return false;
			}
			for ( Map.Entry<K,V> entry : expected.entrySet() ) {
				V valueExpected = entry.getValue();
				V valueActual = actual.get( entry.getKey() );
				if ( !eq( valueExpected, valueActual ) ) {
					return false;
				}
			}
		}
		return true;
	}

	public static <T> boolean eq( Collection<T> expected, Collection<T> actual ) {
		if ( expected == null && actual == null ) {
			return true;
		}
		if ( expected != null && actual == null ) {
			return fail( "Expected %s not equals to %s", expected, "null" );
		}
		if ( expected == null && actual != null ) {
			return fail( "Expected %s not equals to %s", "null", actual );
		}

		if ( expected != null && actual != null && !Arrays.equals( expected.toArray( new Object[expected.size()] ), actual.toArray( new Object[actual.size()] ) ) ) {
			return fail( "Expected %s not equals to %s", expected, actual );
		}

		return true;
	}

	public static <T> boolean eq( short[] expected, short[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s is not equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean eq( T expected, T actual ) {
		if ( expected != null && actual != null && !expected.equals( actual ) ) {
			return fail( "Expected %s not equals to %s", expected, actual );
		}

		if ( expected != null && actual == null ) {
			return fail( "Expected %s not equals to %s", expected, "null" );
		}
		if ( expected == null && actual != null ) {
			return fail( "Expected %s not equals to %s", "null", actual );
		}
		return true;
	}

	public static <T> boolean eq( T[] expected, T[] actual ) {
		if ( !Arrays.equals( expected, actual ) ) {
			return fail( "Expected %s not equals to actual %s", expected, actual );
		}
		return true;
	}

	public static boolean fail( String message, Object... parameters ) {
		if ( parameters == null ) {
			parameters = new Object[] { };
		}
		logger.error( String.format( message, parameters ) );
		return false;
	}

	public static boolean ge( BigDecimal reference, BigDecimal actual ) {
		if ( !(actual.compareTo( reference ) >= 0) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( BigInteger reference, BigInteger actual ) {
		if ( !(actual.compareTo( reference ) >= 0) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( byte reference, byte actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( double reference, double actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( float reference, float actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( int reference, int actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( long reference, long actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean ge( short reference, short actual ) {
		if ( !(actual >= reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( BigDecimal reference, BigDecimal actual ) {
		if ( !(actual.compareTo( reference ) > 0) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( BigInteger reference, BigInteger actual ) {
		if ( !(actual.compareTo( reference ) > 0) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( byte reference, byte actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( double reference, double actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( float reference, float actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( int reference, int actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( long reference, long actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean gt( short reference, short actual ) {
		if ( !(actual > reference) ) {
			return fail( "%s is not greater or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean isFalse( boolean v ) {
		if ( v ) {
			return fail( "Value is true" );
		}
		return true;
	}

	public static boolean isNotNull( Object o ) {
		if ( o == null ) {
			return fail( "Object is null" );
		}
		return true;
	}

	public static boolean isNull( Object o ) {
		if ( o != null ) {
			return fail( "%s is not null", o );
		}
		return true;
	}

	public static boolean isTrue( boolean v ) {
		if ( !v ) {
			return fail( "Value is false" );
		}
		return true;
	}

	public static boolean le( byte reference, byte actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean le( double reference, double actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean le( float reference, float actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean le( int reference, int actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean le( long reference, long actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean le( short reference, short actual ) {
		if ( !(actual <= reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( byte reference, byte actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( double reference, double actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( float reference, float actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( int reference, int actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( long reference, long actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static boolean lt( short reference, short actual ) {
		if ( !(actual < reference) ) {
			return fail( "%s is not lower or equal to %s", actual, reference );
		}
		return true;
	}

	public static <T> boolean ne( boolean[] expected, boolean[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( byte[] expected, byte[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( char[] expected, char[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( double[] expected, double[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( float[] expected, float[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( int[] expected, int[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( long[] expected, long[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <K,V> boolean ne( Map<K,V> expected, Map<K,V> actual ) {
		if ( expected == null && actual == null ) {
			return fail( "Both objects are null" );
		}

		if ( expected == null && actual != null ) {
			return true;
		}

		if ( expected != null && actual == null ) {
			return true;
		}
		if ( expected != null && actual != null ) {
			if ( !ne( expected.keySet(), actual.keySet() ) ) {
				return false;
			}
			for ( Map.Entry<K,V> entry : expected.entrySet() ) {
				V valueExpected = entry.getValue();
				V valueActual = actual.get( entry.getKey() );
				if ( !ne( valueExpected, valueActual ) ) {
					return false;
				}
			}
		}
		return true;
	}

	public static <T> boolean ne( Collection<T> expected, Collection<T> actual ) {
		if ( expected == null && actual == null ) {
			return fail( "Both objects are null" );
		}

		if ( expected == null && actual != null ) {
			return true;
		}

		if ( expected != null && actual == null ) {
			return true;
		}
		if ( expected != null && actual != null && Arrays.equals( expected.toArray( new Object[expected.size()] ), actual.toArray( new Object[actual.size()] ) ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( T expected, T actual ) {
		if ( expected == null && actual == null ) {
			return fail( "Both objects are null" );
		}

		if ( expected == null && actual != null ) {
			return true;
		}

		if ( expected != null && actual == null ) {
			return true;
		}

		if ( expected != null && actual != null && expected.equals( actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( short[] expected, short[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean ne( T[] expected, T[] actual ) {
		if ( Arrays.equals( expected, actual ) ) {
			return fail( "Object %s equals to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean notContains( Collection<T> array, T value ) {
		if ( !isNotNull( array ) ) {
			return false;
		}
		if ( !isNotNull( value ) ) {
			return false;
		}
		for ( T v : array ) {
			if ( Validation.eq( v, value ) ) {
				return fail( "Collection does contain %s", value );
			}
		}
		return true;
	}

	public static <T> boolean notContains( T[] array, T value ) {
		if ( !isNotNull( array ) ) {
			return false;
		}
		if ( !isNotNull( value ) ) {
			return false;
		}
		for ( T v : array ) {
			if ( Validation.eq( v, value ) ) {
				return fail( "Array does contain %s", value );
			}
		}
		return true;
	}

	public static <T> boolean notContainsAll( T[] expected, T[] actual ) {
		if ( isNull( expected ) ) {
			return false;
		}
		if ( isNull( actual ) ) {
			return false;
		}
		return notContainsAll( Arrays.asList( expected ), Arrays.asList( actual ) );
	}

	public static <T> boolean notContainsAll( Collection<T> expected, Collection<T> actual ) {
		if ( isNull( expected ) ) {
			return false;
		}
		if ( isNull( actual ) ) {
			return false;
		}
		if ( !expected.containsAll( actual ) ) {
			return true;
		}
		return fail( "Reference collection does not contain all values." );
	}

	public static <K,V> boolean notContainsEntry( Map<K,V> map, K key, V value ) {
		if ( !isNotNull( map ) ) {
			return false;
		}
		if ( !isNotNull( key ) ) {
			return false;
		}
		if ( map.containsKey( key ) && Validation.eq( map.get( key ), value ) ) {
			return fail( "Map does contain key %s value %s pair", key, value );
		}
		return true;
	}

	public static <K,V> boolean notContainsKey( Map<K,V> map, K key ) {
		if ( !isNotNull( map ) ) {
			return false;
		}
		if ( !isNotNull( key ) ) {
			return false;
		}
		if ( !map.containsKey( key ) ) {
			return fail( "Map does not contain key %s", key );
		}
		return true;
	}

	public static <K,V> boolean notContainsValue( Map<K,V> map, V value ) {
		if ( !isNotNull( map ) ) {
			return false;
		}
		if ( !isNotNull( value ) ) {
			return false;
		}
		if ( map.containsValue( value ) ) {
			return fail( "Map does contain value %s", value );
		}
		return true;
	}

	public static <T> boolean notEmpty( Collection<T> value ) {
		return sizeNe( value, 0 );
	}

	public static <T> boolean sizeNe( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() == expectedSize ) {
			return fail( "Collection length %s is equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T,V> boolean notEmpty( Map<T,V> value ) {
		return sizeNe( value, 0 );
	}

	public static <T,V> boolean sizeNe( Map<T,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() == expectedSize ) {
			return fail( "Collection length %s is equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean notEmpty( T[] value ) {
		return sizeNe( value, 0 );
	}

	public static <T> boolean sizeNe( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length == expectedSize ) {
			return fail( "Array length %s is equal to expected value %s", array.length, expectedSize );
		}
		return true;
	}

	public static <T> boolean same( T expected, T actual ) {
		if ( expected != actual ) {
			return fail( "Object %s not same to %s", expected, actual );
		}
		return true;
	}

	public static <T> boolean sizeGe( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() >= expectedSize ) {
			return fail( "Collection length %s is not greater or equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <K,V> boolean sizeGe( Map<K,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() >= expectedSize ) {
			return fail( "Map length %s is not greater or equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeGe( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length >= expectedSize ) {
			return fail( "Array length %s is not greater or equal to expected value %s", array.length, expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeGt( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() > expectedSize ) {
			return fail( "Collection length %s is not greater to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <K,V> boolean sizeGt( Map<K,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() > expectedSize ) {
			return fail( "Map length %s is not greater to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeGt( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length > expectedSize ) {
			return fail( "Array length %s is not greater than expected value %s", array.length, expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeLe( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() <= expectedSize ) {
			return fail( "Collection length %s is not lower or equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T,V> boolean sizeLe( Map<T,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() <= expectedSize ) {
			return fail( "Map length %s is not lower or equal to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeLe( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length <= expectedSize ) {
			return fail( "Array length %s is not lower or equal to expected value %s", array.length, expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeLt( Collection<T> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() < expectedSize ) {
			return fail( "Collection length %s is not lower to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T,V> boolean sizeLt( Map<T,V> array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.size() < expectedSize ) {
			return fail( "Collection length %s is not lower to expected value %s", array.size(), expectedSize );
		}
		return true;
	}

	public static <T> boolean sizeLt( T[] array, int expectedSize ) {
		if ( array == null ) {
			return fail( "Array is null" );
		}
		if ( array.length < expectedSize ) {
			return fail( "Array length %s is not lower than expected value %s", array.length, expectedSize );
		}
		return true;
	}

	private static Logger logger = LoggerFactory.getLogger( Validation.class );
}
